# -*- coding: utf-8 -*-
"""
活动管理 - 视图函数
"""
import requests
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse, HttpResponseBadRequest
from django.views.decorators.http import require_http_methods
from django.utils import timezone
from django.db.models import Q
from datetime import datetime
import json
from .models import (
    Activity, ActivityType, ActivityRegistration,
    GroupRegistration, ActivityCheckIn
)
from social.models import ActivityComment, ActivityRating
import json


def activity_list(request):
    """活动列表页面"""
    # 获取活动类型用于筛选
    activity_types = ActivityType.objects.all().order_by('-sort_order', 'name')
    
    # 获取所有发布的活动，按创建时间倒序排列
    activities = Activity.objects.filter(status='published').order_by('-created_at')
    
    context = {
        'activity_types': activity_types,
        'activities': activities,
        'page_title': '发现活动'
    }
    
    return render(request, 'activities/list.html', context)


def activity_detail(request, activity_id):
    """活动详情页面"""
    activity = get_object_or_404(Activity, id=activity_id)

    # 增加浏览次数
    activity.view_count += 1
    activity.save(update_fields=['view_count'])

    context = {
        'activity': activity,
    }

    return render(request, 'activities/detail.html', context)


@login_required
def activity_create(request):
    """创建活动页面"""
    # 获取所有活动类型，按排序和名称排序
    activity_types = ActivityType.objects.all().order_by('-sort_order', 'name')
    
    context = {
        'activity_types': activity_types,
    }
    
    return render(request, 'activities/create.html', context)


@login_required
def activity_edit(request, activity_id):
    """编辑活动页面"""
    activity = get_object_or_404(Activity, id=activity_id, creator=request.user)

    context = {
        'activity': activity,
    }

    return render(request, 'activities/edit.html', context)


@login_required
def my_activities(request):
    """我的活动页面"""
    return render(request, 'activities/my_activities.html')


# ========== API视图 ==========

@require_http_methods(["GET"])
def api_activity_list(request):
    """获取活动列表API - 支持多种筛选条件"""
    try:
        # 基础查询：只显示已发布的活动
        query = Activity.objects.filter(status='published')
        
        # 筛选条件处理
        activity_type_id = request.GET.get('type')
        if activity_type_id:
            query = query.filter(activity_type_id=activity_type_id)
            
        # 费用筛选
        fee_filter = request.GET.get('fee', 'all')
        if fee_filter == 'free':
            query = query.filter(is_free=True)
        elif fee_filter == 'paid':
            query = query.filter(is_free=False)
            
        # 状态筛选（即将开始/进行中）
        status_filter = request.GET.get('status', 'all')
        now = timezone.now()
        if status_filter == 'upcoming':
            query = query.filter(start_time__gt=now)
        elif status_filter == 'ongoing':
            query = query.filter(start_time__lte=now, end_time__gte=now)
            
        # 日期筛选
        date_filter = request.GET.get('date')
        if date_filter:
            try:
                # 尝试解析日期格式
                filter_date = datetime.strptime(date_filter, '%Y-%m-%d').date()
                # 筛选当天的活动
                start_of_day = timezone.make_aware(datetime.combine(filter_date, datetime.min.time()))
                end_of_day = timezone.make_aware(datetime.combine(filter_date, datetime.max.time()))
                query = query.filter(
                    (Q(start_time__gte=start_of_day) & Q(start_time__lte=end_of_day)) |
                    (Q(end_time__gte=start_of_day) & Q(end_time__lte=end_of_day)) |
                    (Q(start_time__lte=start_of_day) & Q(end_time__gte=end_of_day))
                )
            except ValueError:
                # 日期格式错误，忽略该筛选条件
                pass
                
        # 参与人数筛选
        participants_filter = request.GET.get('participants', 'all')
        if participants_filter == 'few':
            query = query.filter(max_participants__lt=10)
        elif participants_filter == 'medium':
            query = query.filter(max_participants__gte=10, max_participants__lte=50)
        elif participants_filter == 'many':
            query = query.filter(max_participants__gt=50)
            
        # 搜索功能
        search_keyword = request.GET.get('search', '').strip()
        if search_keyword:
            query = query.filter(Q(title__icontains=search_keyword) | 
                                Q(description__icontains=search_keyword) |
                                Q(location_name__icontains=search_keyword))
        
        # 排序功能
        sort_by = request.GET.get('sort', 'created_at')
        sort_order = request.GET.get('order', 'desc')
        
        # 处理特殊排序
        if sort_by == 'popularity':
            # 优化热门度排序算法
            query = sorted(query, key=lambda x: (x.current_participants / x.max_participants if x.max_participants > 0 else 0) * x.view_count, reverse=(sort_order == 'desc'))
        elif sort_by == 'view_count':
            # 按浏览量排序
            order_by = f'-{sort_by}' if sort_order == 'desc' else sort_by
            query = query.order_by(order_by)
        else:
            order_by = f'-{sort_by}' if sort_order == 'desc' else sort_by
            query = query.order_by(order_by)
        
        # 分页处理 - 优化默认值以提高性能
        page = request.GET.get('page', 1)
        page_size = request.GET.get('page_size', 12)  # 减小默认页面大小
        
        try:
            page = int(page)
            page_size = int(page_size)
            # 增加限制以优化性能
            if page < 1:
                page = 1
            if page_size < 1 or page_size > 50:
                page_size = 12
        except ValueError:
            page = 1
            page_size = 12
            
        # 转换为列表以支持自定义排序后的分页
        activity_list = list(query)
        total = len(activity_list)
        
        start = (page - 1) * page_size
        end = start + page_size
        paged_activities = activity_list[start:end]
        
        # 格式化响应数据
        results = []
        for activity in paged_activities:
            results.append({
                'id': activity.id,
                'title': activity.title,
                'description': activity.description,
                'cover_image': activity.cover_image.url if activity.cover_image else None,
                'activity_type': {
                    'id': activity.activity_type.id if activity.activity_type else None,
                    'name': activity.activity_type.name if activity.activity_type else '其他'
                },
                'creator': {
                    'id': activity.creator.id,
                    'username': activity.creator.username,
                    'nickname': activity.creator.nickname,
                    'avatar': activity.creator.avatar.url if activity.creator.avatar else None,
                },
                'start_time': activity.start_time.isoformat(),
                'end_time': activity.end_time.isoformat(),
                'location_name': activity.location_name,
                'max_participants': activity.max_participants,
                'current_participants': activity.current_participants,
                'is_free': activity.is_free,
                'fee': str(activity.fee),
                'view_count': activity.view_count,
                'comment_count': activity.comment_count,
                'created_at': activity.created_at.isoformat(),
            })
        
        return JsonResponse({
            'code': 200,
            'data': {
                'results': results,
                'pagination': {
                    'total': total,
                    'page': page,
                    'page_size': page_size,
                    'total_pages': (total + page_size - 1) // page_size
                }
            }
        })
    
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'获取活动列表失败：{str(e)}'
        }, status=500)


# 活动类型API已移除
# @require_http_methods(["GET"])
# def api_activity_types(request):
#     """获取所有活动类型API"""
#     pass


@require_http_methods(["GET"])
def api_activity_detail(request, activity_id):
    """获取活动详情API"""
    try:
        activity = Activity.objects.get(id=activity_id)

        data = {
            'id': activity.id,
            'title': activity.title,
            'description': activity.description,
            'cover_image': activity.cover_image.url if activity.cover_image else None,
            'activity_type': {
                'id': activity.activity_type.id if activity.activity_type else None,
                'name': activity.activity_type.name if activity.activity_type else '其他'
            },
            'creator': {
                'id': activity.creator.id,
                'username': activity.creator.username,
                'nickname': activity.creator.nickname,
                'avatar': activity.creator.avatar.url if activity.creator.avatar else None,
            },
            'start_time': activity.start_time.isoformat(),
            'end_time': activity.end_time.isoformat(),
            'location_name': activity.location_name,
            'location_address': activity.location_address,
            'latitude': float(activity.latitude),
            'longitude': float(activity.longitude),
            'max_participants': activity.max_participants,
            'current_participants': activity.current_participants,
            'is_free': activity.is_free,
            'fee': str(activity.fee),
            'status': activity.status,
            'view_count': activity.view_count,
            'comment_count': activity.comment_count,
            'rating_count': activity.rating_count,
            'rating_average': float(activity.rating_average),
        }

        return JsonResponse({
            'code': 200,
            'data': data
        })

    except Activity.DoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '活动不存在'
        }, status=404)


@login_required
@require_http_methods(["POST"])
def api_upload_image(request):
    """上传图片API - 支持任意尺寸图片"""
    try:
        if 'image' not in request.FILES:
            return JsonResponse({
                'code': 400,
                'message': '请选择图片文件'
            }, status=400)
        
        image_file = request.FILES['image']
        
        # 验证文件类型（支持所有常见图片格式）
        allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/bmp', 'image/svg+xml']
        if image_file.content_type not in allowed_types:
            return JsonResponse({
                'code': 400,
                'message': '只支持图片文件（JPG、PNG、GIF、WEBP、BMP、SVG）'
            }, status=400)
        
        # 验证文件大小（10MB，增加限制）
        if image_file.size > 10 * 1024 * 1024:
            return JsonResponse({
                'code': 400,
                'message': '图片大小不能超过10MB'
            }, status=400)
        
        # 生成文件名
        import uuid
        from django.utils import timezone
        ext = image_file.name.split('.')[-1]
        filename = f"activity_{timezone.now().strftime('%Y%m%d%H%M%S')}_{uuid.uuid4().hex[:8]}.{ext}"
        
        # 保存文件
        from django.core.files.storage import default_storage
        file_path = default_storage.save(f'activities/{filename}', image_file)
        file_url = default_storage.url(file_path)
        
        return JsonResponse({
            'code': 200,
            'message': '上传成功',
            'data': {
                'url': file_url,
                'path': file_path
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'上传失败：{str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def api_activity_create(request):
    """创建活动API - 增强错误处理"""
    try:
        # 解析请求数据
        data = json.loads(request.body)
        
        # 打印调试信息
        import logging
        logger = logging.getLogger(__name__)
        logger.info(f"收到创建活动请求，用户：{request.user.username}")
        logger.info(f"请求数据：{data}")
        
        # 验证必填字段
        required_fields = ['title', 'description', 'start_time', 'end_time', 
                          'location_name', 'location_address', 'max_participants']
        missing_fields = [field for field in required_fields if not data.get(field)]
        if missing_fields:
            return JsonResponse({
                'code': 400,
                'message': f'缺少必填字段：{", ".join(missing_fields)}'
            }, status=400)
        
        # 验证活动类型
        if not data.get('activity_type'):
            return JsonResponse({
                'code': 400,
                'message': '请选择活动类型'
            }, status=400)
        
        # 处理可选的报名截止时间
        registration_deadline = data.get('registration_deadline')
        if registration_deadline == '':
            registration_deadline = None
        
        # 创建活动
        activity = Activity.objects.create(
            title=data['title'],
            description=data['description'],
            cover_image=data.get('cover_image', ''),
            activity_type_id=data.get('activity_type'),
            creator=request.user,
            start_time=data['start_time'],
            end_time=data['end_time'],
            location_name=data['location_name'],
            location_address=data['location_address'],
            latitude=float(data.get('latitude', 0)),
            longitude=float(data.get('longitude', 0)),
            max_participants=int(data['max_participants']),
            is_free=bool(data.get('is_free', True)),
            fee=float(data.get('fee', 0)) if not data.get('is_free', True) else 0,
            status=data.get('status', 'published'),
            allow_group_registration=bool(data.get('allow_group_registration', False)),
            group_discount=float(data.get('group_discount', 0)),
            registration_deadline=registration_deadline,
        )
        
        logger.info(f"活动创建成功，ID：{activity.id}")
        
        # 尝试更新用户创建活动数（如果字段存在）
        try:
            if hasattr(request.user, 'created_activities_count'):
                request.user.created_activities_count += 1
                request.user.save(update_fields=['created_activities_count'])
        except Exception as e:
            logger.warning(f"更新用户创建活动数失败：{str(e)}")
            # 不影响活动创建，继续执行

        return JsonResponse({
            'code': 200,
            'message': '创建成功',
            'data': {'id': activity.id}
        })

    except KeyError as e:
        return JsonResponse({
            'code': 400,
            'message': f'缺少必填字段：{str(e)}'
        }, status=400)
    
    except ValueError as e:
        return JsonResponse({
            'code': 400,
            'message': f'数据格式错误：{str(e)}'
        }, status=400)
    
    except Exception as e:
        import traceback
        error_trace = traceback.format_exc()
        logger = logging.getLogger(__name__)
        logger.error(f"创建活动失败：{str(e)}")
        logger.error(f"错误堆栈：{error_trace}")
        
        return JsonResponse({
            'code': 500,
            'message': f'创建失败：{str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def api_activity_register(request, activity_id):
    """报名活动API"""
    try:
        activity = get_object_or_404(Activity, id=activity_id)

        # 检查是否已报名
        if ActivityRegistration.objects.filter(
                user=request.user,
                activity=activity,
                status='registered'
        ).exists():
            return JsonResponse({
                'code': 400,
                'message': '您已经报名过了'
            }, status=400)

        # 检查是否已满
        if activity.is_full():
            return JsonResponse({
                'code': 400,
                'message': '活动名额已满'
            }, status=400)

        # 检查是否可以报名
        if not activity.can_register():
            return JsonResponse({
                'code': 400,
                'message': '活动已截止报名'
            }, status=400)

        # 创建报名记录
        data = json.loads(request.body)
        registration = ActivityRegistration.objects.create(
            user=request.user,
            activity=activity,
            note=data.get('note', ''),
            status='registered'
        )

        # 更新活动参与人数
        activity.current_participants += 1
        activity.save(update_fields=['current_participants'])

        # 更新用户参与活动数
        request.user.joined_activities_count += 1
        request.user.save(update_fields=['joined_activities_count'])

        return JsonResponse({
            'code': 200,
            'message': '报名成功'
        })

    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'报名失败：{str(e)}'
        }, status=500)


@require_http_methods(["GET"])
def api_activity_types(request):
    """获取活动类型列表API"""
    types = ActivityType.objects.all().order_by('-sort_order', 'name')

    results = [{
        'id': t.id,
        'name': t.name,
        'description': t.description,
        'is_system': t.is_system,
    } for t in types]

    return JsonResponse({
        'code': 200,
        'data': {
            'results': results
        }
    })


@require_http_methods(["GET"])
def api_activity_participants(request, activity_id):
    """获取活动参与者列表API"""
    activity = get_object_or_404(Activity, id=activity_id)

    registrations = ActivityRegistration.objects.filter(
        activity=activity,
        status='registered'
    ).select_related('user')

    results = [{
        'user': {
            'id': r.user.id,
            'username': r.user.username,
            'nickname': r.user.nickname,
            'avatar': r.user.avatar.url if r.user.avatar else None,
        },
        'registered_at': r.registered_at.isoformat(),
        'is_checked_in': r.is_checked_in,
    } for r in registrations]

    return JsonResponse({
        'code': 200,
        'data': {
            'results': results
        }
    })


@login_required
@require_http_methods(["GET"])
def api_registration_status(request, activity_id):
    """检查用户报名状态API"""
    is_registered = ActivityRegistration.objects.filter(
        user=request.user,
        activity_id=activity_id,
        status='registered'
    ).exists()

    return JsonResponse({
        'code': 200,
        'data': {
            'is_registered': is_registered
        }
    })


@require_http_methods(["GET"])
def api_statistics(request):
    """获取平台统计数据API"""
    from django.contrib.auth import get_user_model
    from django.db.models import Count

    User = get_user_model()

    # 统计数据
    total_activities = Activity.objects.filter(status='published').count()
    total_users = User.objects.filter(is_active=True).count()

    # 今日活动（今天开始的活动）
    today = timezone.now().date()
    today_activities = Activity.objects.filter(
        status='published',
        start_time__date=today
    ).count()

    # 热门活动（参与人数多的）
    hot_activities = Activity.objects.filter(
        status='published',
        current_participants__gte=10
    ).count()

    return JsonResponse({
        'code': 200,
        'data': {
            'total_activities': total_activities,
            'total_users': total_users,
            'today_activities': today_activities,
            'hot_activities': hot_activities,
        }
    })


# 地图视图
def map_view(request):
    """显示地图页面（增强版，包含浏览器定位功能）"""
    return render(request, 'activities/map_enhancements.html', {
        'amap_key': settings.AMAP_CONFIG['WEB_KEY']
    })


def style_showcase(request):
    """设计系统展示页面"""
    return render(request, 'activities/style_showcase.html')


def geocode(request):
    """地理编码：地址转坐标"""
    address = request.GET.get('address', '')
    if not address:
        return JsonResponse({'error': '地址参数缺失'}, status=400)

    url = 'https://restapi.amap.com/v3/geocode/geo'
    params = {
        'key': settings.AMAP_CONFIG['WEB_KEY'],
        'address': address,
        'output': 'json'
    }

    try:
        response = requests.get(url, params=params)
        data = response.json()
        return JsonResponse(data)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)


def reverse_geocode(request):
    """逆地理编码：坐标转地址"""
    lng = request.GET.get('lng', '')
    lat = request.GET.get('lat', '')

    if not lng or not lat:
        return JsonResponse({'error': '坐标参数缺失'}, status=400)

    url = 'https://restapi.amap.com/v3/geocode/regeo'
    params = {
        'key': settings.AMAP_CONFIG['WEB_KEY'],
        'location': f'{lng},{lat}',
        'output': 'json',
        'extensions': 'all'
    }

    try:
        response = requests.get(url, params=params)
        data = response.json()
        return JsonResponse(data)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)


@csrf_exempt
def save_location(request):
    """保存用户位置（示例）"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            lng = data.get('lng')
            lat = data.get('lat')
            address = data.get('address')
            activity_id = data.get('activity_id')

            if activity_id:
                # 更新活动位置信息
                from .models import Activity
                activity = Activity.objects.get(id=activity_id)
                activity.latitude = lat
                activity.longitude = lng
                activity.location_address = address
                activity.save()

                return JsonResponse({
                    'status': 'success',
                    'message': '位置保存成功',
                    'data': {
                        'latitude': lat,
                        'longitude': lng,
                        'address': address
                    }
                })
            else:
                # 临时保存，用于创建活动时
                return JsonResponse({
                    'status': 'success',
                    'message': '位置信息已获取',
                    'data': {
                        'latitude': lat,
                        'longitude': lng,
                        'address': address
                    }
                })
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)})
    return JsonResponse({'error': '仅支持POST请求'}, status=400)


def get_nearby_activities(request):
    """获取附近的活动"""
    lat = request.GET.get('lat')
    lng = request.GET.get('lng')
    radius = request.GET.get('radius', 5000)  # 默认5公里

    if not lat or not lng:
        return JsonResponse({'error': '坐标参数缺失'}, status=400)

    # 这里可以实现基于地理位置的活动查询
    from .models import Activity
    from django.db.models import F, Func, Value, FloatField
    from django.db.models.functions import Radians, Sin, Cos, ACos

    # 简化版的距离计算
    activities = Activity.objects.filter(
        status='published'
    ).extra(
        where=[f"""
            (6371 * acos(cos(radians({lat})) * cos(radians(latitude)) * 
            cos(radians(longitude) - radians({lng})) + sin(radians({lat})) * 
            sin(radians(latitude)))) < {int(radius) / 1000}
        """]
    )[:20]

    results = []
    for activity in activities:
        results.append({
            'id': activity.id,
            'title': activity.title,
            'latitude': float(activity.latitude),
            'longitude': float(activity.longitude),
            'location_name': activity.location_name,
            'start_time': activity.start_time.isoformat(),
        })

    return JsonResponse({'activities': results})


def search_city_activities(request):
    """根据城市搜索活动"""
    city_name = request.GET.get('city', '').strip()
    if not city_name:
        return JsonResponse({'error': '城市参数缺失'}, status=400)

    # 使用高德地图地理编码获取城市坐标
    url = 'https://restapi.amap.com/v3/geocode/geo'
    params = {
        'key': settings.AMAP_CONFIG['WEB_KEY'],
        'address': city_name,
        'output': 'json'
    }

    try:
        response = requests.get(url, params=params)
        data = response.json()

        if data['status'] == '1' and data['geocodes']:
            location = data['geocodes'][0]['location'].split(',')
            lng = float(location[0])
            lat = float(location[1])

            # 搜索该城市范围内的活动
            radius = request.GET.get('radius', 20000)  # 默认20公里

            # 使用数据库的地理查询
            from django.db.models import F, Func, Value, FloatField
            from django.db.models.functions import Radians, Sin, Cos, ACos

            activities = Activity.objects.filter(
                status='published'
            ).extra(
                where=[f"""
                    (6371 * acos(cos(radians({lat})) * cos(radians(latitude)) * 
                    cos(radians(longitude) - radians({lng})) + sin(radians({lat})) * 
                    sin(radians(latitude)))) < {int(radius) / 1000}
                """]
            )[:50]  # 限制返回数量

            results = []
            for activity in activities:
                results.append({
                    'id': activity.id,
                    'title': activity.title,
                    'latitude': float(activity.latitude),
                    'longitude': float(activity.longitude),
                    'location_name': activity.location_name,
                    'start_time': activity.start_time.isoformat(),
                    'activity_type': {
                        'id': activity.activity_type.id if activity.activity_type else None,
                        'name': activity.activity_type.name if activity.activity_type else '其他'
                    },
                    'creator': {
                        'nickname': activity.creator.nickname,
                    },
                    'current_participants': activity.current_participants,
                    'max_participants': activity.max_participants,
                })

            return JsonResponse({
                'city': city_name,
                'center': {'lng': lng, 'lat': lat},
                'activities': results,
                'count': len(results)
            })
        else:
            return JsonResponse({'error': '未找到该城市'}, status=404)

    except Exception as e:
        return JsonResponse({'error': f'搜索失败：{str(e)}'}, status=500)